<?php

namespace App\Listeners;

use App\Common\Constant\Params;
use App\Events\OrderEmployed;
use App\Models\MasterStatistic;
use App\Models\MerchantTradeLog;
use App\Models\Order;
use App\Models\OrderOffer;
use App\Models\OrderStatus;
use App\Notifications\OrderNotifications\OrderEmployedNotification;
use App\Services\IMerchantService;
use App\Services\ISystemService;
use App\Services\ISystemTaskService;
use DB;
use Illuminate\Cache\Events\CacheHit;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;

class OrderEmployedListener implements ShouldQueue
{

    use InteractsWithQueue;

    public $queue = 'order';

    public $tries = 3;

    public $timeout = 30;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  CacheHit  $event
     * @return void
     */
    public function handle(OrderEmployed $event)
    {
        $trade_log = MerchantTradeLog::find($event->trade_id);
        if(!$trade_log){
            throw new \Exception('miss trade log');
        }

        foreach (array_filter($trade_log['order_number_list']) as $order_id){
            $order = Order::find($order_id);
            if(!$order){
                throw new \Exception('miss order of order_id: '.$order_id);
            }

            $ret = resolve(ISystemService::class)->raiseBalance($trade_log->id,$order->merchant_id,Params::USER_TYPE_MERCHANT,$order->merchant_price);
            if(!$ret){
                throw new \Exception('system balance update fail of order_id: '.$order->id);
            }

            $offer = OrderOffer::where(['order_id' => $order->id, 'master_id' => $order->master_id])->first();
            if(!$offer){
                throw new \Exception('miss offer of order_id: '.$order->id);
            }

            $ret = OrderStatus::where('order_id', $order->id)->take(1)->update(['merchant_status' => Params::ORDER_MERCHANT_STATUS_PAID]);
            if(!$ret){
                throw new \Exception('status update fail of order_id: '.$order->id);
            }

            $ret = $offer->update(['status' => Params::OFFER_STATUS_EMPLOYED]);
            if(!$ret){
                throw new \Exception('offer status update fail of order_id: '.$order->id);
            }

            $ret = MasterStatistic::where('master_id',$order->master_id)->take(1)->update(['order_count'=>DB::raw('order_count + 1')]);
            if(!$ret){
                throw new \Exception('order count increase fail of order_id: '.$order->id);
            }

            $order->master->notify(new OrderEmployedNotification($order));
        }

        if ($trade_log->source == Params::TRADE_SOURCE_BALANCE){
            $ret = resolve(IMerchantService::class)->genBalanceHistory($trade_log->id);
            if(!$ret){
                throw new \Exception('merchant balance update fail');
            }
        }


    }

    public function failed(OrderEmployed $event, \Exception $exception)
    {
        //
    }
}
